import base64
import shutil

from dynaconf import FlaskDynaconf
from flask import abort, jsonify, request, current_app, app
from flask_restful import Resource, reqparse
from flask_simplelogin import login_required
import os
from project_name.models import accounts, db
from urllib.parse import urlparse, parse_qs
from werkzeug.utils import safe_join, secure_filename
from project_name.base import Admin_DIR, User_DIR, source_file
from pathlib import Path

from project_name.utils import build_tree, get_real_path


class GetFileListResource(Resource):
    def post(self):
        try:
            parser = reqparse.RequestParser()
            parser.add_argument('path', type=str, required=True, help='currentPath is required')
            data = parser.parse_args()
            current_path = os.path.join(Path(current_app.static_folder, data['path']))
            print(current_path)
            listdir = []
            for item in Path(current_path).iterdir():
                if item.is_dir():
                    listdir.append({
                        "name": item.name,
                        "type": 'directory',
                        "size": "0",
                    })

            return jsonify({"code": 200, "message": "获取文件夹成功", "data": listdir})
        except Exception as e:
            return jsonify({"code": 404, "message": str(e)})


class UpdateUserResource(Resource):
    def put(self):
        parser = reqparse.RequestParser()
        parser.add_argument('ID', type=str, required=True, help='ID is required')
        parser.add_argument('new_userpassword', type=str, required=True, help='new_userpassword is required')
        data = parser.parse_args()

        user = accounts.query.get(data["ID"])
        if user:
            user.password = data["new_userpassword"]
            db.session.commit()
            return jsonify({"code": 200, "message": "成功", "data": data})
        return jsonify({"code": 404, "message": "编辑失败", "data": data})


class DeleteUserResource(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('delete_id', type=str, required=True, help='delete_id is required')
        data = parser.parse_args()

        user = accounts.query.get(data["delete_id"])
        if user:
            db.session.delete(user)
            db.session.commit()
            return jsonify({"code": 200, "message": "成功"})
        return jsonify({"code": 404, "message": "User not found"})


class CreateFolderResource(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('path', type=str, required=True, help='path is required')
        parser.add_argument('folderName', type=str, required=True, help='folderName is required')
        data = parser.parse_args()

        try:
            base_path = data['path']
            folder_name = secure_filename(data['folderName'])

            if '..' in base_path or '..' in folder_name:
                return jsonify({"status": "error", "message": "非法路径"}), 403

            full_path = os.path.join(Admin_DIR, base_path, folder_name)

            if os.path.exists(full_path):
                return jsonify({"status": "error", "message": "文件夹已存在"}), 400

            os.makedirs(full_path)
            return jsonify({"status": "success", "message": "创建成功", "path": full_path})
        except Exception as e:
            return jsonify({"status": "error", "message": str(e)}), 500


ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'xlsx'}  # 允许的文件类型


def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


class UploadFileResource(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        # Admin/..../....
        parser.add_argument('currentPath', type=str, required=True)
        parser.add_argument('files', type=list, location='json', required=True)
        args = parser.parse_args()

        try:
            current_path = get_real_path(args['currentPath'], ',')
            # 确保目录存在
            os.makedirs(os.path.join(current_app.static_folder, current_path), exist_ok=True)

            for file_data in args['files']:
                file_name = file_data['name']
                file_path = get_real_path(file_data['relativePath'], '/')
                base64_data = file_data['data']

                # 解码Base64并保存文件
                file_bytes = base64.b64decode(base64_data)
                save_path = os.path.join(current_app.static_folder, current_path, file_path)
                os.makedirs(os.path.dirname(save_path), exist_ok=True)
                with open(os.path.join(save_path, file_name), 'wb') as f:
                    f.write(file_bytes)

            return {'code': 200, 'message': '文件上传成功'}

        except Exception as e:
            return {'code': 400, 'message': str(e)}


class DeleteFileResource(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('path', type=str, required=True, help='path is required')
        parser.add_argument('type', type=str, required=True, help='type is required')
        data = parser.parse_args()

        try:
            full_path = os.path.join(Admin_DIR, data['path'])

            if not os.path.exists(full_path):
                return jsonify({"status": "error", "message": "文件不存在"}), 404

            is_dir = os.path.isdir(full_path)
            if (data['type'] == 'file' and is_dir) or (data['type'] == 'directory' and not is_dir):
                return jsonify({"status": "error", "message": "类型不匹配"}), 400

            if is_dir:
                shutil.rmtree(full_path)
            else:
                os.remove(full_path)

            return jsonify({"status": "success", "message": "删除成功"})
        except Exception as e:
            return jsonify({"status": "error", "message": str(e)}), 500


class DownloadFileResource(Resource):
    def get(self):
        relative_path = request.args.get('path', '')
        filename = request.args.get('file', '')

        if not relative_path or not filename:
            return jsonify({"status": "error", "message": "缺少参数"}), 400

        try:
            base_dir = os.path.abspath(Admin_DIR)
            full_path = os.path.join(base_dir, relative_path)
            target_path = os.path.join(full_path, filename)

            if not os.path.exists(target_path):
                return jsonify({"status": "error", "message": "文件不存在"}), 404

            if os.path.isfile(target_path):
                return send_from_directory(directory=full_path, path=filename, as_attachment=True)

            elif os.path.isdir(target_path):
                memory_file = BytesIO()
                with zipfile.ZipFile(memory_file, 'w', zipfile.ZIP_DEFLATED) as zf:
                    for root, _, files in os.walk(target_path):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arcname = os.path.relpath(file_path, start=target_path)
                            zf.write(file_path, arcname)

                memory_file.seek(0)
                return send_file(
                    path_or_file=memory_file,
                    download_name=f"{filename}.zip",
                    as_attachment=True,
                    mimetype='application/zip'
                )
        except Exception as e:
            return jsonify({"status": "error", "message": str(e)}), 500


class SendFileResource(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('users', type=list, location='json', required=True, help='users is required')
        parser.add_argument('fileNames', type=list, location='json', required=True, help='fileNames is required')
        parser.add_argument('filePath', type=str, location='json', required=True, help='filePath is required')
        data = parser.parse_args()

        try:
            users = data['users']
            file_names = data['fileNames']
            file_path = data['filePath']

            for file_name in file_names:
                for user in users:
                    src_file = os.path.join(Admin_DIR, file_path, file_name)
                    if not os.path.exists(src_file):
                        return jsonify({"code": "400", "message": f"源文件 '{src_file}' 不存在"})

                    dst_dir = os.path.join(User_DIR, user)
                    os.makedirs(dst_dir, exist_ok=True)

                    dst_file = os.path.join(dst_dir, file_name)

                    if os.path.isfile(src_file):
                        shutil.copy2(src_file, dst_file)
                    elif os.path.isdir(src_file):
                        shutil.copytree(src_file, dst_file)

            return jsonify({"code": 200, "message": "文件发送成功"})
        except Exception as e:
            return jsonify({"code": 400, "message": str(e)})


class UpdatePasswordResource(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('username', type=str, required=True, help='username is required')
        parser.add_argument('old_password', type=str, required=True, help='old_password is required')
        parser.add_argument('new_password', type=str, required=True, help='new_password is required')
        data = parser.parse_args()

        username = str(data['username'])
        password = str(data['old_password'])
        Accounts = accounts.query.filter_by(username=username).first()

        if Accounts:
            if password == Accounts.password:
                Accounts.password = data["new_password"]
                db.session.commit()
                return jsonify({"code": 200, "message": "修改密码成功", "return_data": {"id_type": Accounts.id_type}})
            else:
                return jsonify({"code": 401, "message": "用户名或密码错误"})
        else:
            return jsonify({"code": 404, "message": "用户不存在"})


class LoginResource(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('username', type=str, required=True, help='username is required')
        parser.add_argument('password', type=str, required=True, help='password is required')
        data = parser.parse_args()

        username = str(data['username'])
        password = str(data['password'])
        Accounts = accounts.query.filter_by(username=username).first()
        if Accounts:
            if password == Accounts.password:
                return jsonify({"code": 200, "return_data": {
                    "id": Accounts.id,
                    "username": Accounts.username,
                    "idType": Accounts.id_type,
                    "parentId": Accounts.parent_account_id,
                }})
            else:
                return jsonify({"code": 404, "message": "用户名或密码错误"})
        else:
            return jsonify({"code": 404, "message": "用户不存在"})


class TestResource(Resource):
    def get(self):
        print(current_app.config['dev_url'])
        print(current_app.config['prd_url'])
        return jsonify({"code": 200, "message": "服务已启动"})
